﻿#define _CRT_SECURE_NO_WARNINGS 1

/* 
自实现strstr函数的功能 
https://legacy.cplusplus.com/reference/cstring/strstr/?kw=strstr
博客：
https://blog.csdn.net/sobercq/article/details/136187589
*/

#include<stdio.h>
#include<assert.h>

//思路一
//遍历源字符串，找到与字符串2首字母相同的字符，进入循环2，
//但在进入之前需要保存一份当前位置，然后我们再去利用新开辟出来的两个指针去遍历两个字符串，
//如果有不相等的地方，那么字符串肯定是走不到尾巴的，也就是不可能等于'\0',
//此时继续遍历字符串1，直到字符串1遍历结束，完成整个字符串的查找，没有就返回NULL。

char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	char* str3 = NULL;
	char* str4 = NULL;
	while (*str1 != '\0')
	{
		str4 = str2;
		str3 = str1;
		while (*str3 == *str4 && *str3 && *str4)
		{
			str3++;
			str4++;
		}
		if (*str4 == '\0')
			return str1;
		str1++;
	}
	return NULL;
}

//代码优化解析：
//1.不希望在遍历字符串的时候所有的值都被修改，包括后续返回的地址，所以全部都可以用const修饰
//2.当第二个字符串为空的时候，返回字符串1的地址，
//就相当于你让我在一个字符串里找什么都没有的东西，库里设计是返回第一个字符串地址
//3.不希望改变原有的地址，str1，和str2，所以再创建一个指针变量用来代替上述str1的使用

const char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	const char* cp = str1;
	const char* s1 = NULL;
	const char* s2 = NULL;

	if (*str2 == '\0')
	{
		return str1;
	}

	while (*cp)
	{
		s1 = cp;
		s2 = str2;
		while (*s1 == *s2 && *s1 != '\0' && *s2 != '\0')
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return cp;
		}
		cp++;
	}
	return NULL;
}

void Judge(char* p)
{
	if (p != NULL)
		printf("%s \n", p);
	else
		printf("找不到\n");
}

int main()
{
	char arr1[] = "hello CILMY23";
	char arr2[] = "C";
	char arr3[] = "lllC";
	char arr4[] = "This is a simple string";
	char arr5[] = "";

	char* ret = strstr(arr1, arr2);
	Judge(ret);
	ret = strstr(arr2, arr1);
	Judge(ret);

	ret = strstr(arr3, arr1);
	Judge(ret);

	ret = strstr(arr3, arr2);
	Judge(ret);

	ret = strstr(arr1, arr3);
	Judge(ret);

	ret = strstr(arr2, arr3);
	Judge(ret);

	ret = strstr(arr4, "simple");
	Judge(ret);

	ret = strstr(arr1, arr5);
	Judge(ret);

	return 0;
}